/**
* Created with CLion.
* User:Lenovo
* Date:2023-05-16
* Time:3:52
* Description:双向带头循环链表
*/

#include "List.h"

LTNode *BuyLTNode(LTDataType x)
{
    LTNode *newNode = (LTNode *)malloc(sizeof(LTNode));
    if (!newNode)
    {
        perror("malloc failed");
    }
    newNode -> data = x;
    return newNode;
}

LTNode *LTInit()
{
    LTNode *pHead = BuyLTNode(-1);
    pHead -> next = pHead;
    pHead -> prev = pHead;
    return pHead;
}

void LTPrint(LTNode *pHead)
{
    assert(pHead);

    printf("guard <==> ");
    LTNode *cur = pHead -> next;
    while (cur != pHead)
    {
        printf("%d <==> ", cur -> data);
        cur = cur -> next;
    }
    printf("guard\n");
}

bool LTEmpty(LTNode *pHead)
{
    assert(pHead);

    return (pHead == pHead -> next);
}

void LTPushBack(LTNode *pHead, LTDataType x)
{
    assert(pHead);

    LTNode *tail = pHead -> prev;
    LTNode *newNode = BuyLTNode(x);

    tail -> next = newNode;
    newNode -> next = pHead;
    newNode -> prev = tail;
    pHead -> prev = newNode;
}

void LTPushFront(LTNode *pHead, LTDataType x)
{
    assert(pHead);

    LTNode *newNode = BuyLTNode(x);
    newNode -> next = pHead -> next;
    newNode -> next -> prev = newNode;
    newNode -> prev = pHead;
    pHead -> next = newNode;
}

void LTPopBack(LTNode *pHead)
{
    assert(pHead);
    assert(!LTEmpty(pHead));

    LTNode *tmp = pHead -> prev;
    tmp -> prev -> next = pHead;
    pHead -> prev = tmp -> prev;

    free(tmp);
    tmp = NULL;
}

void LTPopFront(LTNode *pHead)
{
    assert(pHead);
    assert(!LTEmpty(pHead));

    LTNode *tmp = pHead -> next;
    pHead -> next = tmp -> next;
    tmp -> next -> prev = pHead;

    free(tmp);
    tmp = NULL;
}

LTNode *LTFind(LTNode *pHead, LTDataType x)
{
    assert(pHead);
    assert(!LTEmpty(pHead));

    LTNode *cur = pHead -> next;
    while (cur != pHead)
    {
        if (cur -> data == x)
        {
            return cur;
        }
        cur = cur -> next;
    }
    return NULL;
}

void LTInsertBefore(LTNode *pos, LTDataType x)
{
    assert(pos);

    LTNode *newNode = BuyLTNode(x);
    newNode -> next = pos;
    newNode -> prev = pos -> prev;
    pos -> prev -> next = newNode;
    pos -> prev = newNode;
}

void LTErase(LTNode *pos)
{
    assert(pos);
    assert(!LTEmpty(pos));

    pos -> prev -> next = pos -> next;
    pos -> next -> prev = pos -> prev;

    free(pos);
    pos = NULL;
}

void LTDestroy(LTNode *pHead)
{
    assert(pHead);

    LTNode *cur = pHead -> next;
    while (cur != pHead)
    {
        LTNode *next = cur -> next;
        free(cur);
        cur = NULL;
    }
    free(pHead);
}